home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / REGION.C < prev    next >
C/C++ Source or Header  |  1993-05-20  |  6KB  |  259 lines

  1. #include "jam.h"
  2. /*
  3.  *        Region based commands.
  4.  * The routines in this file
  5.  * deal with the region, that magic space
  6.  * between "." and mark. Some functions are
  7.  * commands. Some functions are just for
  8.  * internal use.
  9.  */
  10. #include    "def.h"
  11.  
  12. static int rn_(getregion,(REGION *rp));
  13. static int rn_(setsize,(REGION *rp, RSIZE size)); 
  14.  
  15. /*
  16.  * Kill the region. Ask "getregion"
  17.  * to figure out the bounds of the region.
  18.  * Move "." to the start, and kill the characters.
  19.  */
  20. /*ARGSUSED*/
  21. killregion(f, n)
  22. int f, n;
  23. {
  24.   register int    s;
  25.   REGION        region;
  26.  
  27.   if (curbp->b_flag & BFVIEW)
  28.     {
  29.       ttbeep();
  30.       return FALSE;
  31.     }
  32.   if (filetimechanged(curbp))
  33.     return(FALSE);
  34.   clearUndo(curbp);
  35.  
  36.    if ((s=getregion(®ion)) != TRUE)
  37.     return (s);
  38.    if ((lastflag&CFKILL) == 0)        /* This is a kill type    */
  39.     kdelete();            /* command, so do magic */
  40.    thisflag |= CFKILL;            /* kill buffer stuff.    */
  41.    curwp->w_dotp = region.r_linep;
  42.    curwp->w_doto = region.r_offset;
  43.    return (ldelete(region.r_size, KFORW));
  44. }
  45.  
  46. /*
  47.  * Copy all of the characters in the
  48.  * region to the kill buffer. Don't move dot
  49.  * at all. This is a bit like a kill region followed
  50.  * by a yank.
  51.  */
  52. /*ARGSUSED*/
  53. copyregion(f, n)
  54. int f, n;
  55. {
  56.     register LINE    *linep;
  57.     register int    loffs;
  58.     register int    s;
  59.     REGION        region;
  60.     VOID        kdelete();
  61.  
  62.     if ((s=getregion(®ion)) != TRUE)
  63.         return s;
  64.     if ((lastflag&CFKILL) == 0)        /* Kill type command.    */
  65.         kdelete();
  66.     thisflag |= CFKILL;
  67.     linep = region.r_linep;            /* Current line.    */
  68.     loffs = region.r_offset;        /* Current offset.    */
  69.     while (region.r_size--) {
  70.         if (loffs == llength(linep)) {    /* End of line.        */
  71.             if ((s=kinsert('\n', KFORW)) != TRUE)
  72.                 return (s);
  73.             linep = lforw(linep);
  74.             loffs = 0;
  75.         } else {            /* Middle of line.    */
  76.             if ((s=kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
  77.                 return s;
  78.             ++loffs;
  79.         }
  80.     }
  81.         ewprintf("Region copied.");
  82.     return TRUE;
  83. }
  84.  
  85. /*
  86.  * Lower case region. Zap all of the upper
  87.  * case characters in the region to lower case. Use
  88.  * the region code to set the limits. Scan the buffer,
  89.  * doing the changes. Call "lchange" to ensure that
  90.  * redisplay is done in all buffers.
  91.  */
  92. /*ARGSUSED*/
  93. lowerregion(f, n)
  94. int f, n;
  95. {
  96.     register LINE    *linep;
  97.     register int    loffs;
  98.     register int    c;
  99.     register int    s;
  100.     REGION        region;
  101.  
  102.   if (curbp->b_flag & BFVIEW)
  103.     {
  104.       ttbeep();
  105.       return FALSE;
  106.     }
  107.   if (filetimechanged(curbp))
  108.     return(FALSE);
  109.   clearUndo(curbp);
  110.  
  111.     if ((s=getregion(®ion)) != TRUE)
  112.         return s;
  113.     lchange(WFHARD);
  114.     linep = region.r_linep;
  115.     loffs = region.r_offset;
  116.     while (region.r_size--) {
  117.                 changelineflag(linep, TRUE);
  118.         if (loffs == llength(linep)) {
  119.             linep = lforw(linep);
  120.             loffs = 0;
  121.         } else {
  122.             c = lgetc(linep, loffs);
  123.             if (ISUPPER(c) != FALSE)
  124.                 lputc(linep, loffs, (char)TOLOWER(c));
  125.             ++loffs;
  126.         }
  127.     }
  128.     return TRUE;
  129. }
  130.  
  131. /*
  132.  * Upper case region. Zap all of the lower
  133.  * case characters in the region to upper case. Use
  134.  * the region code to set the limits. Scan the buffer,
  135.  * doing the changes. Call "lchange" to ensure that
  136.  * redisplay is done in all buffers.
  137.  */
  138. /*ARGSUSED*/
  139. upperregion(f, n)
  140. int f, n;
  141. {
  142.     register LINE    *linep;
  143.     register int    loffs;
  144.     register int    c;
  145.     register int    s;
  146.     REGION        region;
  147.     VOID        lchange();
  148.  
  149.   if (curbp->b_flag & BFVIEW)
  150.     {
  151.       ttbeep();
  152.       return FALSE;
  153.     }
  154.   if (filetimechanged(curbp))
  155.     return(FALSE);
  156.   clearUndo(curbp);
  157.  
  158.     if ((s=getregion(®ion)) != TRUE)
  159.         return s;
  160.     lchange(WFHARD);
  161.     linep = region.r_linep;
  162.     loffs = region.r_offset;
  163.     while (region.r_size--) {
  164.                 changelineflag(linep, TRUE);
  165.         if (loffs == llength(linep)) {
  166.             linep = lforw(linep);
  167.             loffs = 0;
  168.         } else {
  169.             c = lgetc(linep, loffs);
  170.             if (ISLOWER(c) != FALSE)
  171.                 lputc(linep, loffs, (char)TOUPPER(c));
  172.             ++loffs;
  173.         }
  174.     }
  175.     return TRUE;
  176. }
  177.  
  178. /*
  179.  * This routine figures out the bound of the region
  180.  * in the current window, and stores the results into the fields
  181.  * of the REGION structure. Dot and mark are usually close together,
  182.  * but I don't know the order, so I scan outward from dot, in both
  183.  * directions, looking for mark. The size is kept in a long. At the
  184.  * end, after the size is figured out, it is assigned to the size
  185.  * field of the region structure. If this assignment loses any bits,
  186.  * then we print an error. This is "type independent" overflow
  187.  * checking. All of the callers of this routine should be ready to
  188.  * get an ABORT status, because I might add a "if regions is big,
  189.  * ask before clobberring" flag.
  190.  */
  191. static int getregion(rp) 
  192. register REGION *rp; 
  193. {
  194.     register LINE    *flp;
  195.     register LINE    *blp;
  196.     register RSIZE  fsize;            /* Long now.        */
  197.     register RSIZE    bsize;
  198.  
  199.     if (curwp->w_markp == NULL) {
  200.         ewprintf("No mark set in this window");
  201.         return (FALSE);
  202.     }
  203.     if (curwp->w_dotp == curwp->w_markp) {    /* "r_size" always ok.    */
  204.         rp->r_linep = curwp->w_dotp;
  205.         if (curwp->w_doto < curwp->w_marko) {
  206.             rp->r_offset = curwp->w_doto;
  207.             rp->r_size = (RSIZE) (curwp->w_marko-curwp->w_doto);
  208.         } else {
  209.             rp->r_offset = curwp->w_marko;
  210.             rp->r_size = (RSIZE) (curwp->w_doto-curwp->w_marko);
  211.         }
  212.         return TRUE;
  213.     }
  214.     flp = blp = curwp->w_dotp;        /* Get region size.    */
  215.     bsize = curwp->w_doto;
  216.     fsize = llength(flp)-curwp->w_doto+1;
  217.     while (lforw(flp)!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  218.         if (lforw(flp) != curbp->b_linep) {
  219.             flp = lforw(flp);
  220.             if (flp == curwp->w_markp) {
  221.                 rp->r_linep = curwp->w_dotp;
  222.                 rp->r_offset = curwp->w_doto;
  223.                 return (setsize(rp,
  224.                     (RSIZE) (fsize+curwp->w_marko)));
  225.             }
  226.             fsize += llength(flp)+1;
  227.         }
  228.         if (lback(blp) != curbp->b_linep) {
  229.             blp = lback(blp);
  230.             bsize += llength(blp)+1;
  231.             if (blp == curwp->w_markp) {
  232.                 rp->r_linep = blp;
  233.                 rp->r_offset = curwp->w_marko;
  234.                 return (setsize(rp,
  235.                     (RSIZE) (bsize-curwp->w_marko)));
  236.             }
  237.         }
  238.     }
  239.     ewprintf("Bug: lost mark");        /* Gak!            */
  240.     return FALSE;
  241. }
  242.  
  243. /*
  244.  * Set size, and check for overflow.
  245.  */
  246. static int setsize(rp, size) 
  247. register REGION *rp; 
  248. register RSIZE size; 
  249. {
  250.  
  251.     rp->r_size = size;
  252.     if (rp->r_size != size) {
  253.         ewprintf("Region is too large");
  254.         return FALSE;
  255.     }
  256.     return TRUE;
  257. }
  258.  
  259.